import { Injectable } from '@nestjs/common';
import { Request } from 'express';

/**
 * 请求工具类
 * 基于 NestJS 实现 Java 风格的 RequestUtils
 * 对应 Java: RequestUtils
 */
@Injectable()
export class RequestUtil {
  private request: Request;

  /**
   * 设置当前请求对象
   * @param request 请求对象
   */
  setRequest(request: Request): void {
    this.request = request;
  }

  /**
   * 获取当前请求对象
   * @returns 请求对象
   */
  getRequest(): Request {
    return this.request;
  }

  /**
   * 获取请求域名
   * @returns 域名
   */
  getRequestDomain(): string {
    return this.request?.get('host') || '';
  }

  /**
   * 获取请求协议
   * @returns 协议
   */
  getRequestSecure(): string {
    return this.request?.protocol || 'http';
  }

  /**
   * 获取请求IP地址
   * @returns IP地址
   */
  getRequestIpAddr(): string {
    if (!this.request) {
      return '';
    }

    // 获取真实IP地址
    const forwarded = this.request.get('x-forwarded-for');
    if (forwarded) {
      return forwarded.split(',')[0].trim();
    }

    const realIp = this.request.get('x-real-ip');
    if (realIp) {
      return realIp;
    }

    return this.request.ip || this.request.connection.remoteAddress || '';
  }

  /**
   * 获取请求参数映射
   * @returns 参数映射
   */
  getParameterMap(): Record<string, string[]> {
    if (!this.request) {
      return {};
    }

    const params: Record<string, string[]> = {};

    // 合并查询参数和路径参数
    const allParams = { ...this.request.query, ...this.request.params };

    for (const key in allParams) {
      if (allParams.hasOwnProperty(key)) {
        const value = allParams[key];
        if (Array.isArray(value)) {
          params[key] = value.map((v) => String(v));
        } else {
          params[key] = [String(value)];
        }
      }
    }

    return params;
  }

  /**
   * 获取请求参数值
   * @param name 参数名
   * @param defaultValue 默认值
   * @returns 参数值
   */
  getParameter(name: string, defaultValue: string = ''): string {
    const params = this.getParameterMap();
    const values = params[name];
    return values && values.length > 0 ? values[0] : defaultValue;
  }

  /**
   * 获取请求参数数组
   * @param name 参数名
   * @returns 参数数组
   */
  getParameterValues(name: string): string[] {
    const params = this.getParameterMap();
    return params[name] || [];
  }

  /**
   * 获取请求头
   * @param name 头名称
   * @returns 头值
   */
  getHeader(name: string): string {
    return this.request?.get(name) || '';
  }

  /**
   * 获取所有请求头
   * @returns 请求头对象
   */
  getHeaders(): Record<string, string | string[] | undefined> {
    return this.request?.headers || {};
  }

  /**
   * 获取请求方法
   * @returns 请求方法
   */
  getMethod(): string {
    return this.request?.method || '';
  }

  /**
   * 获取请求URL
   * @returns 请求URL
   */
  getRequestURL(): string {
    if (!this.request) {
      return '';
    }

    const protocol = this.getRequestSecure();
    const host = this.getRequestDomain();
    const url = this.request.originalUrl || this.request.url;

    return `${protocol}://${host}${url}`;
  }

  /**
   * 获取请求路径
   * @returns 请求路径
   */
  getRequestPath(): string {
    return this.request?.originalUrl || this.request?.url || '';
  }

  /**
   * 获取请求路径（不包含查询参数）
   * @returns 请求路径
   */
  getPath(): string {
    return this.request?.path || '';
  }

  /**
   * 获取查询字符串
   * @returns 查询字符串
   */
  getQueryString(): string {
    return this.request?.url?.split('?')[1] || '';
  }

  /**
   * 获取请求体
   * @returns 请求体
   */
  getBody(): any {
    return this.request?.body;
  }

  /**
   * 获取内容长度
   * @returns 内容长度
   */
  getContentLength(): number {
    const length = this.getHeader('content-length');
    return length ? parseInt(length, 10) : 0;
  }

  /**
   * 是否为Ajax请求
   * @returns 是否为Ajax请求
   */
  isAjax(): boolean {
    const xRequestedWith = this.getHeader('x-requested-with');
    return xRequestedWith === 'XMLHttpRequest';
  }

  /**
   * 是否为移动设备
   * @returns 是否为移动设备
   */
  isMobile(): boolean {
    const userAgent = this.getUserAgent().toLowerCase();
    return /mobile|android|iphone|ipad|phone/i.test(userAgent);
  }

  /**
   * 获取用户代理
   * @returns 用户代理字符串
   */
  getUserAgent(): string {
    return this.getHeader('user-agent');
  }

  /**
   * 获取客户端信息
   * @returns 客户端信息
   */
  getClientInfo(): {
    ip: string;
    userAgent: string;
    referer: string;
    isAjax: boolean;
    isMobile: boolean;
  } {
    return {
      ip: this.getRequestIpAddr(),
      userAgent: this.getUserAgent(),
      referer: this.getHeader('referer'),
      isAjax: this.isAjax(),
      isMobile: this.isMobile(),
    };
  }

  /**
   * 获取请求信息
   * @returns 请求信息
   */
  getRequestInfo(): {
    method: string;
    url: string;
    ip: string;
    userAgent: string;
    timestamp: number;
  } {
    return {
      method: this.getMethod(),
      url: this.getRequestURL(),
      ip: this.getRequestIpAddr(),
      userAgent: this.getUserAgent(),
      timestamp: Date.now(),
    };
  }

  /**
   * 获取请求ID
   * @returns 请求ID
   */
  getRequestId(): string {
    return this.getHeader('x-request-id') || '';
  }

  /**
   * 设置请求ID
   * @param id 请求ID
   */
  setRequestId(id: string): void {
    if (this.request) {
      this.request.headers['x-request-id'] = id;
    }
  }

  /**
   * 获取会话ID
   * @returns 会话ID
   */
  getSessionId(): string {
    return this.getHeader('x-session-id') || '';
  }

  /**
   * 设置会话ID
   * @param id 会话ID
   */
  setSessionId(id: string): void {
    if (this.request) {
      this.request.headers['x-session-id'] = id;
    }
  }

  /**
   * 获取认证令牌
   * @returns 认证令牌
   */
  getAuthToken(): string {
    const authHeader = this.getHeader('authorization');
    if (authHeader && authHeader.startsWith('Bearer ')) {
      return authHeader.substring(7);
    }
    return '';
  }

  /**
   * 获取语言
   * @returns 语言代码
   */
  getLanguage(): string {
    return this.getHeader('accept-language') || 'zh-CN';
  }

  /**
   * 获取时区
   * @returns 时区
   */
  getTimezone(): string {
    return this.getHeader('x-timezone') || 'Asia/Shanghai';
  }
}
